﻿using HSJM.Service.MWS.Core.ShareMode;
using HSJM.Service.MWS.Utility.Logs;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using Newtonsoft.Json;
using Microsoft.Extensions.DependencyInjection;
using HSJM.Service.MWS.Utility;
using HSJM.Service.MWS.Core;
using Microsoft.AspNetCore.Http;
using System.Web;

namespace HSJM.Service.MWS.Filters
{
    /// <summary>
    /// api 日志跟踪类
    /// </summary>
    public class WebApiTrackerAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// 控制器方法执行之前执行此方法
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            if (!context.HttpContext.Items.ContainsKey("executeStartTime"))
            {
                context.HttpContext.Items.Add("executeStartTime", DateTime.Now);
            }
      
            var dataContent = "";
            foreach (string item in context.ActionArguments.Keys)
            {
                dataContent += $"\"{item}\":\"{JsonConvert.SerializeObject(context.ActionArguments[item])}\",";
            }
        
            if (!context.HttpContext.Items.ContainsKey("bodyData"))
            {
                context.HttpContext.Items.Add("bodyData", dataContent);
            }
            WriteLogAsync(context);
            return Task.CompletedTask;
        }

        /// <summary>
        /// 控制器操作结果执行之前调用此方法
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public override Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
        {
            return base.OnResultExecutionAsync(context, next);
        }

        /// <summary>
        /// 控制器操作结果执行之后调用此方法
        /// </summary>
        /// <param name="context"></param>
        public override async void OnActionExecuted(ActionExecutedContext context)
        {
            // 操作结束成功的进行日志记录（新增，修改，删除）
            try
            {
                var actionName = ((ControllerActionDescriptor)context.ActionDescriptor).ActionName.ToLower();
                var controllerName = ((ControllerActionDescriptor)context.ActionDescriptor).ControllerName;
                var menuData = OperationLogInfo.OperationMenuDatas.Find(x => x.ActionPath.Equals(context.HttpContext.Request.Path));
                var flag = !actionName.Contains("plc");
                WMSOperateLogInsertDTO wmsOperateLogInsert = new WMSOperateLogInsertDTO();
                var headerInfo = CustomHeaderHelper.GetCustomHeader();
                //var accountInfo = _accessor.HttpContext.Request.Headers["AccountInfo"].ToString();//.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                //accountInfo = HttpUtility.UrlDecode(accountInfo);
                //var headerInfo = JsonConvert.DeserializeObject<CustomHeader>(accountInfo);
                if ((!context.HttpContext.Request.Method.ToLower().Equals("get")) && flag && headerInfo != null && headerInfo.Id != 0)
                {
                    if (menuData != null)
                    {
                        var result = JsonConvert.DeserializeObject<HttpResponseResultModel<object>>(JsonConvert.SerializeObject(((ObjectResult)context.Result).Value));
                        // 操作成功的增删改 进行记录日志
                        if (result.IsSuccess)
                        {
                            wmsOperateLogInsert.FunctionalModule = menuData.FunctionalModule;
                            wmsOperateLogInsert.OperateContent = menuData.FunctionDesc;
                            wmsOperateLogInsert.OperateType = menuData.FunctionDesc;
                        }
                    }
                    else if (actionName.IndexOf("insert") > -1 || actionName.IndexOf("update") > -1 || actionName.IndexOf("delete") > -1)
                    {
                        if (context.Result != null)
                        {
                            var result = JsonConvert.DeserializeObject<HttpResponseResultModel<object>>(JsonConvert.SerializeObject(((ObjectResult)context.Result).Value));
                            // 操作成功的增删改 进行记录日志
                            if (result.IsSuccess)
                            {
                                var menuInfo = OperationLogInfo.OperationMenuDatas.Find(x => x.ControllerName.Equals(controllerName));
                                if (menuInfo == null)
                                {
                                    menuInfo = new OperationMenuData() { };
                                }
                                wmsOperateLogInsert.FunctionalModule = menuInfo.FunctionalModule;
                                wmsOperateLogInsert.OperateContent = actionName.IndexOf("insert") > -1 ? "新增" : actionName.IndexOf("update") > -1 ? "更新" : "删除" + menuInfo.FunctionDesc;
                                wmsOperateLogInsert.OperateType = actionName.IndexOf("insert") > -1 ? "新增" : actionName.IndexOf("update") > -1 ? "更新" : "删除";
                            }
                        }
                    }
                    else
                    {
                        wmsOperateLogInsert.FunctionalModule = controllerName;
                        wmsOperateLogInsert.OperateContent = actionName;
                        wmsOperateLogInsert.OperateType = "操作";
                    }
                    if (!string.IsNullOrEmpty(wmsOperateLogInsert.FunctionalModule))
                    {
                        var dataContent = "";
                        if (context.HttpContext.Request.HasFormContentType)
                        {
                            var formDatas = context.HttpContext.Request.Form;
                            foreach (string item in formDatas.Keys)
                            {
                                dataContent += $"\"{item}\":\"{formDatas[item]}\",";
                            }
                        }
                        var bodyData = context.HttpContext.Items["bodyData"]?.ToString();
                        if (!string.IsNullOrEmpty(bodyData))
                        {
                            dataContent += bodyData;
                        }
                        wmsOperateLogInsert.DataContent = dataContent;
                        var user = CustomHeaderHelper.GetCustomHeader();
                        if (user != null)
                        {
                            wmsOperateLogInsert.OperaterID = user.Id;
                            wmsOperateLogInsert.OperaterName = user.UserName;
                        }

                        //var wmsOpreateLogApp = CommonServiceProvider.ServiceProvider.GetRequiredService<WMSOperateLogApp>();

                        //await wmsOpreateLogApp.InsertAsync(wmsOperateLogInsert);
                        MyLogger.Logger.Information(JsonConvert.SerializeObject(wmsOperateLogInsert));
                    }
                }
            }
            catch (Exception ex)
            {
            }
            base.OnActionExecuted(context);
        }

        /// <summary>
        /// 写日志
        /// </summary>
        /// <param name="actionContext"></param>
        /// <returns></returns>
        private async Task WriteLogAsync(ActionExecutingContext actionContext)
        {
            var items = actionContext.HttpContext.Items;
            DateTime executeStartTime = DateTime.Parse(items["executeStartTime"].ToString());
            WebApiLogModel logModel = new WebApiLogModel();
            logModel.ExecuteStartTime = executeStartTime;
            logModel.ExecuteEndTime = DateTime.Now;
            //获取Action 参数
            logModel.ActionParams = new Dictionary<string, object>(actionContext.ActionArguments);
            logModel.HttpRequestHeaders = actionContext.HttpContext.Request.Headers.ToString();
            logModel.HttpRequestPath = actionContext.HttpContext.Request.Path;
            logModel.HttpMethod = actionContext.HttpContext.Request.Method;
            logModel.ActionName = ((ControllerActionDescriptor)actionContext.ActionDescriptor).ActionName;
            logModel.ControllerName = ((ControllerActionDescriptor)actionContext.ActionDescriptor).ControllerName;
            logModel.TotalSeconds = (logModel.ExecuteEndTime - logModel.ExecuteStartTime).TotalSeconds;
            logModel.IP = CommonHttpContext.Current.Connection.RemoteIpAddress.ToString();
            //// 使用MongoDB的话，WebApiLogModel 需要继承下MongoDBBaseField
            //   MongoDbHelper<WebApiLogModel> helper = new MongoDbHelper<WebApiLogModel>();
            //  helper.Insert(logModel);
            var json = JsonConvert.SerializeObject(logModel);
            MyLogger.Logger.Information(json + "\r\n");
        }
    }
}
